from lexer.token.token_type import TokenType
from parse.symbol_table.symbol_table import SymbolTable
from parse.symbol_table.constant_variable import ConstantVariable
from parse.symbol_table.pointer import Pointer
from parse.symbol_table.array import Array

class Variable:
    def __init__(self,
                 token_type: TokenType,
                 name: str,
                 init = None):
        self.tokenType = token_type     # 变量类型
        self.name = name                # 变量名
        self.initData = init            # 缓存初始值，延迟处理

        self.scope_path = []            # 变量的作用域
        self.size = 0                   # 变量的大小
        self.isLiteral = False
        self.arraySize = 0
        self.isLeft = False
        self.isInitialized = False
        self.value = 0
        self.offset = 0                 # 局部变量、参数的栈偏移量

    @classmethod
    def getVoid(cls):
        return SymbolTable.voidVar

    def setType(self, token_type: TokenType):
        if token_type == TokenType.KW_VOID:
            raise Exception("不允许使用void变量")
        elif token_type == TokenType.NUMBER:
            self.size = 8   # 整数是4字节
        elif token_type == TokenType.CHAR:
            self.size = 1   # 字符是1字节

    def printValue(self):
        if isinstance(self, ConstantVariable):
            print(self.value)
        else:
            print(self.name)

    def toString(self):
        print(self.tokenType.name)
        if isinstance(self, Pointer):
            print("*")
        print(self.name)
        if isinstance(self, Array):
            print("[%d]", self.length)

        if self.initData:
            print(" = ")
            if self.tokenType == TokenType.KW_INT:
                print(self.value)
            elif self.tokenType == TokenType.KW_CHAR:
                print(self.value)
            elif isinstance(self, Pointer):
                print("<%s>".format(self.name))

        print("; size=%d\n".format(self.size))
        if self.offset > 0:
            print("addr=[rbp+%d]".format(self.offset))
        elif self.name[0] != '<':
            print("addr=<%s>".format(self.name))
        else:
            print("value='%d'".format(self.value))
